home *** CD-ROM | disk | FTP | other *** search
- ;* DPMI.ASM
- ;*
- ;* DPMI functions for protected mode MIDAS
- ;*
- ;* $Id: dpmi.asm,v 1.3 1997/01/16 18:41:59 pekangas Exp $
- ;*
- ;* Copyright 1996,1997 Housemarque Inc.
- ;*
- ;* This file is part of the MIDAS Sound System, and may only be
- ;* used, modified and distributed under the terms of the MIDAS
- ;* Sound System license, LICENSE.TXT. By continuing to use,
- ;* modify or distribute this file you indicate that you have
- ;* read the license and understand and accept it fully.
- ;*
-
- P386
- IDEAL
- JUMPS
-
-
- INCLUDE "lang.inc"
- INCLUDE "errors.inc"
- INCLUDE "dpmi.inc"
-
-
-
- CODESEG
-
-
-
- ;/***************************************************************************\
- ;*
- ;* Function: int dpmiAllocDescriptor(unsigned *descriptor);
- ;*
- ;* Description: Allocate LDT descriptor. Use dpmiFreeDescriptor to deallocate.
- ;*
- ;* Input: unsigned *descriptor pointer to descriptor number
- ;*
- ;* Returns: MIDAS error code. Descriptor number is written to *descriptor.
- ;*
- ;\***************************************************************************/
-
- PROC dpmiAllocDescriptor _funct descriptor : _ptr
- USES _bx
-
- xor _ax,_ax ; DPMI function 0 - alloc LDT descr.
- mov _cx,1 ; allocate one descriptor
- int 31h
- jc @@err
-
- IFDEF __32__
- and eax,0FFFFh
- ENDIF
-
- LOADPTR es,_bx,[descriptor] ; write allocated descriptor to
- mov [_esbx],_ax ; *descriptor
-
- xor _ax,_ax
- jmp @@done
-
- @@err:
- mov _ax,errDPMIFailure
- ERROR ID_dpmiAllocDescriptor
-
- @@done:
- ret
- ENDP
-
-
-
-
- ;/***************************************************************************\
- ;*
- ;* Function: int dpmiFreeDescriptor(unsigned descriptor);
- ;*
- ;* Description: Deallocates an LDT descriptor.
- ;*
- ;* Input: unsigned descriptor descriptor to deallocate
- ;*
- ;* Returns: MIDAS error code
- ;*
- ;\***************************************************************************/
-
- PROC dpmiFreeDescriptor _funct descriptor : _int
- USES _bx
-
- mov _ax,0001h ; DPMI function 1 - free LDT descr.
- mov _bx,[descriptor]
- int 31h
- jc @@err
-
- xor _ax,_ax
- jmp @@done
-
- @@err:
- mov _ax,errInvalidDescriptor
- ERROR ID_dpmiFreeDescriptor
-
- @@done:
- ret
- ENDP
-
-
-
-
- ;/***************************************************************************\
- ;*
- ;* Function: int dpmiSetSegmentBase(unsigned selector, ulong baseAddr);
- ;*
- ;* Description: Changes the 32-bit linear base address of a selector.
- ;*
- ;* Input: unsigned selector selector number
- ;* ulong baseAddr 32-bit linear base address for
- ;* selector
- ;*
- ;* Returns: MIDAS error code.
- ;*
- ;\***************************************************************************/
-
- PROC dpmiSetSegmentBase _funct selector : _int, baseAddr : _long
- USES _bx
-
- mov _ax,0007h ; DPMI function 7 - set segment base
- mov _bx,[selector]
- IFDEF __32__
- xor ecx,ecx
- xor edx,edx
- ENDIF
- mov cx,[word baseAddr+2] ; cx:dx = new base address
- mov dx,[word baseAddr]
- int 31h
- jc @@err
-
- xor _ax,_ax
- jmp @@done
-
- @@err:
- mov _ax,errInvalidDescriptor
- ERROR ID_dpmiSetSegmentBase
-
- @@done:
- ret
- ENDP
-
-
-
-
- ;/***************************************************************************\
- ;*
- ;* Function: int dpmiGetSegmentBase(unsigned selector, ulong *baseAddr);
- ;*
- ;* Description: Reads the 32-bit linear base address of a selector.
- ;*
- ;* Input: unsigned selector selector number
- ;* ulong *baseAddr pointer to the 32-bit linear base
- ;* address of the selector
- ;*
- ;* Returns: MIDAS error code. Selector base address is written to
- ;* *baseAddr.
- ;*
- ;\***************************************************************************/
-
- PROC dpmiGetSegmentBase _funct selector : _int, baseAddr : _ptr
- USES _bx
-
- mov _ax,0006h ; DPMI function 7 - get segment base
- mov _bx,[selector]
- int 31h
- jc @@err
-
- LOADPTR es,_bx,[baseAddr]
- mov [word _esbx],dx ; write segment base address to
- mov [word _esbx+2],cx ; *baseAddr
-
- xor _ax,_ax
- jmp @@done
-
- @@err:
- mov _ax,errInvalidDescriptor
- ERROR ID_dpmiGetSegmentBase
-
- @@done:
- ret
- ENDP
-
-
-
-
- ;/***************************************************************************\
- ;*
- ;* Function: int dpmiSetSegmentLimit(unsigned selector, ulong limit);
- ;*
- ;* Description: Changes the limit of a segment selector.
- ;*
- ;* Input: unsigned selector selector number
- ;* ulong limit 32-bit segment limit
- ;*
- ;* Returns: MIDAS error code.
- ;*
- ;\***************************************************************************/
-
- PROC dpmiSetSegmentLimit _funct selector : _int, limit : _long
- USES _bx
-
- mov _ax,0008h ; DPMI function 8 - set segment limit
- mov _bx,[selector]
- IFDEF __32__
- xor ecx,ecx
- xor edx,edx
- ENDIF
- mov cx,[word limit+2] ; cx:dx = new segment limit
- mov dx,[word limit]
- int 31h
- jc @@err
-
- xor _ax,_ax
- jmp @@done
-
- @@err:
- mov _ax,errDPMIFailure
- ERROR ID_dpmiSetSegmentLimit
-
- @@done:
- ret
- ENDP
-
-
-
-
- ;/***************************************************************************\
- ;*
- ;* Function: int dpmiSetSegmentAccessRights(unsigned selector,
- ;* unsigned accessRights);
- ;*
- ;* Description: Changes the access rights of a selector
- ;*
- ;* Input: unsigned selector selector
- ;* unsigned accessRights new access rights for the segment
- ;*
- ;* Returns: MIDAS error code.
- ;*
- ;\***************************************************************************/
-
- PROC dpmiSetSegmentAccessRights _funct selector : _int, \
- accessRights : _int
- USES _bx
-
- mov _ax,0009h ; DPMI function 9 - set access rights
- mov _bx,[selector]
- mov _cx,[accessRights]
- int 31h
- jc @@err
-
- xor _ax,_ax
- jmp @@done
-
- @@err:
- mov _ax,errDPMIFailure
- ERROR ID_dpmiSetSegmentAccessRights
-
- @@done:
- ret
- ENDP
-
-
-
-
- ;/***************************************************************************\
- ;*
- ;* Function: int dpmiCreateCodeAlias(unsigned codeSelector,
- ;* unsigned *selector);
- ;*
- ;* Description: Creates a data descriptor that has the same base and limit
- ;* as a code segment descriptor. Use dpmiFreeDescriptor() to
- ;* deallocate data descriptor.
- ;*
- ;* Input: unsigned codeSelector code segment selector
- ;* unsigned *selector pointer to data segment selector
- ;*
- ;* Returns: MIDAS error code. New data selector is written to *selector.
- ;*
- ;\***************************************************************************/
-
- PROC dpmiCreateCodeAlias _funct codeSelector : _int, selector : _ptr
- USES _bx
-
- mov _ax,000Ah ; 000Ah - create code alias descr.
- mov _bx,[codeSelector]
- int 31h
- jc @@err
-
- IFDEF __32__
- and eax,0FFFFh
- ENDIF
-
- LOADPTR es,_bx,[selector] ; write selector to *selector
- mov [_esbx],_ax
-
- xor _ax,_ax
- jmp @@done
-
- @@err:
- mov _ax,errDPMIFailure
- ERROR ID_dpmiCreateCodeAlias
-
- @@done:
- ret
- ENDP
-
-
-
-
- ;/***************************************************************************\
- ;*
- ;* Function: int dpmiAllocDOSMem(unsigned numParagraphs, unsigned *segment,
- ;* unsigned *selector);
- ;*
- ;* Description: Allocates memory from DOS free memory pool, below 1MB. Use
- ;* dpmiFreeDOSMem() to deallocate.
- ;*
- ;* Input: unsigned numParagraphs number of paragraphs to allocate
- ;* unsigned *segment pointer to real mode segment
- ;* unsigned *selector pointer to selector
- ;*
- ;* Returns: MIDAS error code. Real mode segment of allocated block is
- ;* written to *segment. Protected mode selector for block is
- ;* written to *selector.
- ;*
- ;\***************************************************************************/
-
- PROC dpmiAllocDOSMem _funct numParagraphs : _int, \
- realSeg : _ptr, selector : _ptr
- USES _bx
-
- mov _ax,0100h ; 0100h - alloc DOS memory block
- mov _bx,[numParagraphs]
- int 31h
- jnc @@ok
-
- cmp _ax,07h ; memory control blocks damaged?
- je @@mcbDamaged
- cmp _ax,08h ; insufficient memory?
- je @@nomemory
-
- mov _ax,errDPMIFailure
- jmp @@err
-
- @@mcbDamaged:
- mov _ax,errHeapCorrupted
- jmp @@err
-
- @@nomemory:
- mov _ax,errOutOfMemory
- jmp @@err
-
- @@ok:
- IFDEF __32__
- and eax,0FFFFh
- and edx,0FFFFh
- ENDIF
- LOADPTR es,_bx,[realSeg]
- mov [_esbx],_ax ; write real mode segment to *segment
- LOADPTR es,_bx,[selector]
- mov [_esbx],_dx ; write selector to *selector
-
- xor _ax,_ax
- jmp @@done
-
- @@err:
- ERROR ID_dpmiAllocDOSMem
-
- @@done:
- ret
- ENDP
-
-
-
-
- ;/***************************************************************************\
- ;*
- ;* Function: dpmiFreeDOSMem(unsigned selector);
- ;*
- ;* Description: Deallocates memory allocated with dpmiAllocDOSMem().
- ;*
- ;* Input: unsigned selector selector for allocated block
- ;*
- ;* Returns: MIDAS error code
- ;*
- ;\***************************************************************************/
-
- PROC dpmiFreeDOSMem _funct selector : _int
- USES _bx
-
- mov _ax,0101h ; 0101h - free DOS memory block
- mov _dx,[selector]
- int 31h
- jc @@error
-
- xor _ax,_ax
- jmp @@done
-
- @@error:
- cmp _ax,07h ; memory control blocks damaged?
- je @@mcbDamaged
- cmp _ax,09h ; incorrect segment?
- je @@badSegment
-
- mov _ax,errDPMIFailure
- jmp @@err
-
- @@mcbDamaged:
- mov _ax,errHeapCorrupted
- jmp @@err
-
- @@badSegment:
- mov _ax,errInvalidDescriptor
-
- @@err:
- ERROR ID_dpmiFreeDOSMem
-
- @@done:
- ret
- ENDP
-
-
-
-
- ;/***************************************************************************\
- ;*
- ;* Function: int dpmiRealModeInt(unsigned intNum,
- ;* dpmiRealCallRegs *registers);
- ;*
- ;* Description: Simulates a real mode interrupt using DPMI service 0x0300.
- ;* *register MUST contain appropriate register values for
- ;* interrupt (CS:IP is ignored).
- ;*
- ;* Input: unsigned intNum interrupt number
- ;* dpmiRealCallRegs *registers DPMI real mode calling struct
- ;*
- ;* Returns: MIDAS error code. Register values returned by the interrupt
- ;* are written to *registers.
- ;*
- ;\***************************************************************************/
-
- PROC dpmiRealModeInt _funct intNum : _int, registers : _ptr
- USES _di,es,_bx
-
- IFDEF __32__
- mov ax,ds
- mov es,ax
- xor ebx,ebx
- xor ecx,ecx
- ELSE
- xor cx,cx
- ENDIF
-
- mov _ax,0300h ; 0300h - simulate real mode interrupt
- mov bl,[byte intNum]
- mov bh,1 ; reset PIC and A20 line
- LOADPTR es,_di,[registers]
- int 31h
- jc @@err
-
- ; es:_di now contains pointer to modified real mode call structure.
- ; The DPMI specs do not clearly state that this is necessarily the
- ; same as the original structure, so for safety we check the pointers
- ; and if they differ copy the data to the original structure:
-
- IFDEF __32__
- mov ax,es
- mov dx,ds
- cmp ax,dx
- jne @@copyregs
- cmp edi,[registers]
- jne @@copyregs
- ELSE
- mov ax,es
- cmp ax,[word registers+2]
- jne @@copyregs
- cmp di,[word registers]
- jne @@copyregs
- ENDIF
-
- ; es:di points to the original structure - the new register values
- ; are at their place.
-
- xor _ax,_ax
- jmp @@done
-
- @@copyregs:
- ; es:_di has changed - copy the new register structure to the old
- ; place:
- push ds _si
-
- mov _si,_di
-
- IFDEF __32__
- mov ax,es
- mov dx,ds
- mov ds,ax
- mov es,dx
- ELSE
- mov ax,es ; ds:_si = es:_di
- mov ds,ax
- ENDIF
- LOADPTR es,_di,[registers]
- mov _cx,SIZE dpmiRealCallRegs
- cld
- rep movsb
-
- pop _si ds
-
- xor _ax,_ax
- jmp @@done
-
- @@err:
- mov _ax,errDPMIFailure
- ERROR ID_dpmiRealModeInt
-
- @@done:
- ret
- ENDP
-
-
-
-
- ;/***************************************************************************\
- ;*
- ;* Function: int dpmiLockMemory(ulong start, ulong numBytes);
- ;*
- ;* Description: Locks a region of memory to prevent it from being paged. The
- ;* memory can be unlocked using dpmiUnlockMemory().
- ;*
- ;* Input: ulong start memory region start address
- ;* ulong numBytes memory region length in bytes
- ;*
- ;* Returns: MIDAS error code
- ;*
- ;\***************************************************************************/
-
- PROC dpmiLockMemory _funct start : _long, numBytes : _long
- USES _si,_di, _bx
-
- mov _ax,0600h ; 0600h - Lock Linear Region
-
- IFDEF __32__
- xor ebx,ebx
- xor ecx,ecx
- xor esi,esi
- xor edi,edi
- ENDIF
-
- mov bx,[word start+2] ; bx:cx = start address
- mov cx,[word start]
- mov si,[word numBytes+2] ; si:di = number of bytes
- mov di,[word numBytes]
-
- int 31h
- jc @@err
-
- xor _ax,_ax
- jmp @@done
-
- @@err:
- mov _ax,errDPMIFailure
- ERROR ID_dpmiLockMemory
-
- @@done:
- ret
- ENDP
-
-
-
-
- ;/***************************************************************************\
- ;*
- ;* Function: int dpmiUnlockMemory(ulong start, ulong numBytes);
- ;*
- ;* Description: Unlocks a region of memory locked with dpmiLockMemory().
- ;*
- ;* Input: ulong start memory region start address
- ;* ulong numBytes memory region length in bytes
- ;*
- ;* Returns: MIDAS error code
- ;*
- ;\***************************************************************************/
-
- PROC dpmiUnlockMemory _funct start : _long, numBytes : _long
- USES _si,_di,_bx
-
- mov _ax,0600h ; 0601h - Unlock Linear Region
-
- IFDEF __32__
- xor ebx,ebx
- xor ecx,ecx
- xor esi,esi
- xor edi,edi
- ENDIF
-
- mov bx,[word start+2] ; bx:cx = start address
- mov cx,[word start]
- mov si,[word numBytes+2] ; si:di = number of bytes
- mov di,[word numBytes]
-
- int 31h
- jc @@err
-
- xor _ax,_ax
- jmp @@done
-
- @@err:
- mov _ax,errDPMIFailure
- ERROR ID_dpmiUnlockMemory
-
- @@done:
- ret
- ENDP
-
-
-
- ;* $Log: dpmi.asm,v $
- ;* Revision 1.3 1997/01/16 18:41:59 pekangas
- ;* Changed copyright messages to Housemarque
- ;*
- ;* Revision 1.2 1996/08/04 11:14:32 pekangas
- ;* All functions now preserve _bx
- ;*
- ;* Revision 1.1 1996/05/22 20:49:33 pekangas
- ;* Initial revision
- ;*
-
-
- END